<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 * @author   howe <howe1995@163.com>
 */

namespace App\Model;

use App\Constant\Database\FriendEnum;
use Hyperf\Database\Model\SoftDeletes;

use function Hyperf\Support\env;

class Friend extends Model
{
    use SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected array $fillable = ['nickname', 'type', 'status', 'unread', 'remark', 'setting'];

    protected array $casts = [
        'setting' => 'json',
    ];

    public function to()
    {
        return $this->belongsTo(User::class, 'friend', 'id');
    }

    public function friend()
    {
        return $this->belongsTo(User::class, 'friend', 'id');
    }

    public function owner()
    {
        return $this->belongsTo(User::class, 'owner', 'id');
    }

    public static function checkIsFriend(int $owner, int $friend, $returnFriend = false): array|bool
    {
        $friend = Friend::query()
            ->where('friend', $owner)
            ->where('owner', $friend)
            ->where('status', FriendEnum::STATUS_PASS)
            ->first(['nickname']);
        $friend = $friend ? $friend->toArray() : [];
        return $returnFriend ? [(bool) $friend, $friend] : (bool) $friend;
    }

    public function getBgFilePathAttribute($value): string
    {
        if (empty($value)) {
            return '';
        }
        if (! str_contains($value, 'http')) {
            return env('STATIC_FILE_URL') . $value;
        }
        return $value;
    }

    public static function findAllFriendIds($user_id)
    {
        return Friend::query()
            ->where('owner', $user_id)
            ->where('status', FriendEnum::STATUS_PASS)
            ->pluck('owner')->toArray();
    }

    /**
     * 获取朋友圈可见好友.
     * @param mixed $reverse
     */
    public static function getMomentCanSeeFriendIds(int $owner, $reverse = false): array
    {
        $seeHimField = $reverse ? 'DontLetHimSeeIt' : 'DontSeeHim';
        $letHimSeeField = $reverse ? 'DontSeeHim' : 'DontLetHimSeeIt';
        $seeHim = Friend::query()->where('owner', $owner)
            ->where('status', FriendEnum::STATUS_PASS)
            ->whereJsonContains('setting', ['FriendPerm' => ['MomentAndStatus' => [$seeHimField => '0'], 'SettingFriendPerm' => 'ALLOW_ALL']])
            ->pluck('friend')->toArray();
        $letHimSee = Friend::query()->where('friend', $owner)
            ->where('status', FriendEnum::STATUS_PASS)
            ->whereJsonContains('setting', ['FriendPerm' => ['MomentAndStatus' => [$letHimSeeField => '0'], 'SettingFriendPerm' => 'ALLOW_ALL']])
            ->pluck('owner')->toArray();
        return array_intersect($seeHim, $letHimSee);
    }

    /**
     * 获取共同好友.
     */
    public static function getPublicFriendIds(int $owner, int $him): array
    {
        $ownerCanSee = self::getMomentCanSeeFriendIds($owner, true);
        if ($owner == $him) {
            return $ownerCanSee;
        }
        if (empty($ownerCanSee)) {
            return [];
        }
        $himCanSee = self::getMomentCanSeeFriendIds($him, true);
        return array_intersect($ownerCanSee, $himCanSee);
    }

    /**
     * 好友设置是否存在.
     */
    public static function checkExistsBySetting(int $owner, int $friend, string $column, string $value): bool
    {
        return self::query()->where('owner', $owner)
            ->where('friend', $friend)
            ->whereRaw("JSON_EXTRACT(setting, '$.{$column}') = '{$value}'")
            ->whereJsonContains('setting', ['FriendPerm' => ['SettingFriendPerm' => 'ALLOW_ALL']])
            ->exists();
    }
}
